home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / admin / linuxcon.000 / linuxcon / linuxconf-1.6 / userconf / groups.c < prev    next >
C/C++ Source or Header  |  1996-06-15  |  5KB  |  263 lines

  1. #include <unistd.h>
  2. #include <grp.h>
  3. #include <sys/stat.h>
  4. #include "../xconf/xconf.h"
  5. #include "../paths.h"
  6. #include "internal.h"
  7. #include "userconf.h"
  8. #include "userconf.m"
  9.  
  10. #define ETC_GTMP "/etc/gtmp"
  11.  
  12. static USERCONF_HELP_FILE help_groups("groups");
  13. static CONFIG_FILE f_group (ETC_GROUP,help_groups,CONFIGF_MANAGED
  14.     ,"root","root",0644);
  15.  
  16. PUBLIC GROUPS::GROUPS()
  17. {
  18.     struct group *p;
  19.     while ((p=getgrent())!=NULL){
  20.         add (new GROUP(p));
  21.     }
  22.     endgrent();
  23.     rstmodified();
  24. }
  25.  
  26. PUBLIC GROUPS::~GROUPS()
  27. {
  28. }
  29. /*
  30.     Get one GROUP specification of the table or NULL
  31. */
  32. PUBLIC GROUP *GROUPS::getitem(int no)
  33. {
  34.     return (GROUP*)ARRAY::getitem(no);
  35. }
  36. /*
  37.     Return the GROUP specification from its name.
  38.     Return NULL if not found.
  39. */
  40. PUBLIC GROUP *GROUPS::getitem(const char *name)
  41. {
  42.     GROUP *ret = NULL;
  43.     int nbg = getnb();
  44.     for (int i=0; i<nbg; i++){
  45.          GROUP *grp = getitem(i);
  46.         if (strcmp(grp->getname(),name)==0){
  47.             ret = grp;
  48.             break;
  49.         }
  50.     }
  51.     return ret;
  52. }
  53. /*
  54.     Return the gid of a group from its name.
  55.     Return -1 if there is no group with this name.
  56. */
  57. PUBLIC int GROUPS::getgid(const char *name)
  58. {
  59.     GROUP *grp = getitem(name);
  60.     return grp == NULL ? -1 : grp->getgid();
  61. }
  62. /*
  63.     Write the /etc/group file with proper locking
  64. */
  65. PUBLIC int GROUPS::write()
  66. {
  67.     int ret = -1;
  68.     FILE *fout = f_group.fopen (ETC_GTMP,"w");
  69.     if (fout != NULL){
  70.         int nbu = getnb();
  71.         for (int i=0; i<nbu; i++){
  72.             getitem(i)->write(fout);
  73.         }
  74.         fclose(fout);
  75.         unlink(ETC_GROUP ".OLD");
  76.         link(ETC_GROUP, ETC_GROUP ".OLD");
  77.         unlink(ETC_GROUP);
  78.         link(ETC_GTMP, ETC_GROUP);
  79.         unlink(ETC_GTMP);
  80.         chmod(ETC_GROUP, 0644);
  81.         ret = 0;
  82.     }
  83.     return ret;
  84. }
  85. /*
  86.     Return the name of the group to use when creating new user (default)
  87. */
  88. PUBLIC const char *GROUPS::getdefault()
  89. {
  90.     /* #Specification: userconf / groups / default for creation
  91.         The default group is "users". If this group does not
  92.         exist. then the group "group" is used. If none of those
  93.         group exist, then no default group is proposed to
  94.         the user.
  95.     */
  96.     /* #todo: userconf / groups and users / default for creation
  97.         It is not clear if a default setup should exist such
  98.         as /etc/default/useradd and could be edited by userconf.
  99.  
  100.         Currently, we assumed that the default user group is 1.
  101.     */
  102.     const char *ret = NULL;
  103.     if (getitem("users")!=NULL){
  104.         ret = "users";
  105.     }else if (getitem("group")!=NULL){
  106.         ret = "group";
  107.     }
  108.     return ret;
  109. }
  110.  
  111. /*
  112.     Get one GROUP specification of the table or NULL from his GID
  113. */
  114. PUBLIC GROUP *GROUPS::getfromgid(int gid)
  115. {
  116.     GROUP *ret = NULL;
  117.     int nbg = getnb();
  118.     for (int i=0; i<nbg; i++){
  119.          GROUP *grp = getitem(i);
  120.         if (grp->getgid() == gid){
  121.             ret = grp;
  122.             break;
  123.         }
  124.     }
  125.     return ret;
  126. }
  127.  
  128. /*
  129.     Allocate an unused group ID.
  130. */
  131. PUBLIC int GROUPS::getnew()
  132. {
  133.     /* #Specification: userconf / groups / group ID allocation
  134.         When creating a new group, the group ID may be left
  135.         blank. An unused group ID will be allocated. The first
  136.         one unused will be allocated.
  137.  
  138.         We assume that a maximum of 1000 group may be configured.
  139.     */
  140.     for (int i=1; i<1000; i++){
  141.         if (getfromgid(i)==NULL) break;
  142.     }
  143.     return i;
  144. }
  145.  
  146. static int cmpbyname (ARRAY_OBJ *o1, ARRAY_OBJ *o2)
  147. {
  148.     GROUP *g1 = (GROUP*) o1;
  149.     GROUP *g2 = (GROUP*) o2;
  150.     return strcmp(g1->getname(),g2->getname());
  151. }
  152. /*
  153.     Sort the array of group by name
  154. */
  155. PUBLIC void GROUPS::sortbyname()
  156. {
  157.     sort (cmpbyname);
  158. }
  159. /*
  160.     General edition (addition/deletion/correction) of /etc/group
  161. */
  162.  
  163. PUBLIC int GROUPS::edit()
  164. {
  165.     int ret = -1;
  166.     int choice = 0;
  167.     USERS users;
  168.     sortbyname();
  169.     while (1){
  170.         int nbg = getnb();
  171.         const char **menuopt = (const char**)malloc_err((nbg*2+1)
  172.             *sizeof(char*));
  173.         const char **ptsort = menuopt;
  174.         for (int i=0; i<nbg; i++){
  175.             *ptsort++ = getitem(i)->getname();
  176.             *ptsort++ = " ";
  177.         }
  178.         *ptsort = NULL;
  179.         MENU_STATUS code = xconf_menu (
  180.             MSG_U(T_GROUPS,"User groups")
  181.             ,MSG_U(I_GROUPS,"You can edit, add, or delete groups")
  182.             ,help_groups
  183.             ,NULL
  184.             ,NULL
  185.             ,NULL
  186.             ,MSG_U(I_TOADD,"to add a new definition")
  187.             ,menuopt,choice);
  188.         if (code == MENU_ESCAPE || code == MENU_QUIT){
  189.             break;
  190.         }else{
  191.             GROUP *grp = getitem(menuopt[choice*2]);
  192.             if (code == MENU_OK){
  193.                 int status = grp->edit(users,*this);
  194.                 if (status != -1){
  195.                     if (status == 1) remove_del (grp);
  196.                     write();
  197.                     ret = 0;
  198.                 }
  199.             }else if (perm_rootaccess(
  200.                 MSG_R(P_GROUPDB))){
  201.                 if (code == MENU_ADD){
  202.                     GROUP *ngrp = new GROUP;
  203.                     if (ngrp->edit(users,*this)==0){
  204.                         add (ngrp);
  205.                         write ();
  206.                         ret = 0;
  207.                     }else{
  208.                         delete ngrp;
  209.                     }
  210.                 }
  211.             }
  212.         }
  213.     }
  214.     return ret;
  215. }
  216.  
  217. void groups_edit()
  218. {
  219.     GROUPS groups;
  220.     groups.edit();
  221. }
  222.  
  223. /*
  224.     Get the ID of a group. Create it if it does not exist.
  225.     Return -1 if it was not created.
  226. */
  227. int group_getcreate (const char *name, const char *reason)
  228. {
  229.     GROUPS groups;
  230.     int gid = groups.getgid (name);
  231.     if (gid == -1){
  232.         char buf[1000];
  233.         sprintf (buf
  234.             ,MSG_U(I_GROUPCREATE
  235.              ,"The group %s does not exist on your\n"
  236.               "system. It is needed to %s\n"
  237.               "\n"
  238.               "Do you want to create it ? (why not)")
  239.             ,name,reason);
  240.  
  241.         if (xconf_yesno(MSG_U(Q_GROUPCREATE,"Mandatory group creation")
  242.             ,buf,help_nil) == MENU_YES){
  243.             gid = groups.getnew();
  244.             GROUP *grp = new GROUP (name,"*",gid,NULL);
  245.             groups.add (grp);
  246.             groups.write();
  247.         }
  248.     }
  249.     return gid;
  250. }
  251.  
  252.  
  253. #ifdef TEST
  254.  
  255. int main (int argc, char *argv[])
  256. {
  257.     groups_edit();
  258. }
  259.  
  260. #endif
  261.  
  262.  
  263.